package com.dronff.gvm.rtda.heap;

import com.dronff.gvm.GvmEnv;
import com.dronff.gvm.interfaces.Allocatable;
import com.dronff.gvm.memorymanager.Memory;
import com.dronff.gvm.memorymanager.impl.AllocatableMemoryImpl;
import com.dronff.gvm.memorymanager.impl.MiniMemoryImpl;
import lombok.Data;
import lombok.experimental.Accessors;

/**
 * @author: tyf
 * @date: 2022/9/9 9:50
 * @description: todo(堆区)
 */
@Data
@Accessors(chain = true)
public class Heap implements Allocatable {
    private AllocatableMemoryImpl memory;
    private YoungGen youngGen;
    private OldGen oldGen;
    public static Heap newInstance() throws IllegalAccessException {
        Heap heap = new Heap();
        heap
                .setMemory(AllocatableMemoryImpl.newInstance(GvmEnv.getInstance().getMaximumHeap()))
                .setYoungGen(new YoungGen(heap))
                .setOldGen(new OldGen(heap));
        return heap;
    }
    private static class YoungGen{
        private AllocatableMemoryImpl memory;
        private YoungGen(Heap heap) throws IllegalAccessException {
            this.memory = heap.getMemory().allocRegion(GvmEnv.getInstance().getYoungGenSize());
        }
        private static class Eden{

        }
        private static class Survive{

        }
    }
    private static class OldGen{
        private AllocatableMemoryImpl memory;
        private OldGen(Heap heap) throws IllegalAccessException {
            this.memory = heap.getMemory().allocRegion(GvmEnv.getInstance().getMaximumHeap() - GvmEnv.getInstance().getYoungGenSize());
        }
    }
    @Override
    public MiniMemoryImpl alloc(int size) throws IllegalAccessException {
        return youngGen.memory.alloc(size);
    }

    @Override
    public Memory allocRegion(int size) throws OutOfMemoryError, IllegalAccessException {
        throw new IllegalAccessException("Disallow splitting heap memory into smaller region memory");
    }
}
